#include "Account.hh"

Account::Account(const string& id, Customer* owner)
    : accountID(id), balance(0.0), owner(owner) {}

string Account::getID() const {
    return accountID;
}

double Account::getBalance() const {
    return balance;
}

Customer* Account::getOwner() const {
    return owner;
}

void Account::addTransaction(shared_ptr<Transaction> t) {
    transactions.push_back(t);
}

const vector<shared_ptr<Transaction>>& Account::getTransactions() const {
    return transactions;
}


void Account::showMenu() {
    int choice;
    double amount;

    while (true) {
        cout << "\n===== Bank Account: " << getID() << " (" << getAccountType() << ") =====\n";
        cout << "Account holder: " << owner->getName() << "\n";
        cout << fixed << setprecision(2);
        cout << "Balance: ¥" << getBalance() << "\n";

        cout << "\n1. Deposit\n";
        cout << "2. Withdraw\n";
        cout << "3. Transfer\n";
        cout << "4. View transaction history\n";
        cout << "5. Generate bank account report\n";
        cout << "6. Return to customer page\n";
        cout << "\nPlease choose: ";

        if (!(cin >> choice)) {
            cout << "Invalid input. Please enter a number.\n";
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
            continue;
        }

        switch (choice) {
            case 1:
                cout << "Enter amount to deposit: ¥";
                cin >> amount;
                if (amount > 0) {
                    string note = "ATM Deposit";
                    if (deposit(amount, note)) {
                        cout << "Deposit successful.\n";
                    } else {
                        cout << "Deposit failed.\n";
                    }
                } else {
                    cout << "Invalid amount.\n";
                }
                break;

            case 2:
                cout << "Enter amount to withdraw: ¥";
                cin >> amount;
                if (amount > 0) {
                    string note = "ATM Withdraw";
                    if (withdraw(amount, note)) {
                        cout << "Withdrawal successful.\n";
                    } else {
                        cout << "Withdrawal failed. Insufficient funds or policy violation.\n";
                    }
                } else {
                    cout << "Invalid amount.\n";
                }
                break;

            case 3: {
                string toID;
                cout << "Enter destination account ID: ";
                cin >> toID;
                cout << "Enter amount to transfer: ¥";
                cin >> amount;
                if (amount > 0) {
                    Account* toAccount = owner->findAccountByID(toID);
                    if (toAccount) {
                        string note = "Transfer to " + toID;
                        if (transfer(toAccount, amount, note)) {
                            cout << "Transfer successful.\n";
                        } else {
                            cout << "Transfer failed. Insufficient funds or policy violation.\n";
                        }
                    } else {
                        cout << "Destination account not found under current customer.\n";
                    }
                } else {
                    cout << "Invalid amount.\n";
                }
                break;
            }

            case 4:
                if (transactions.empty()) {
                    cout << "No transactions yet.\n";
                } else {
                    cout << "\nTransaction History:\n";
                    for (const auto& t : transactions) {
                        cout << t->toString() << "\n";
                    }
                }
                break;

            case 5:
                ReportGenerator::generateAccountTransactionReport(this);
                break;
            
            case 6:
                return;

            default:
                cout << "Invalid choice. Please try again.\n";
        }

        cin.ignore(numeric_limits<streamsize>::max(), '\n');
    }
}

